#ifndef BASE_UTILS_TIME_UTIL_H
#define BASE_UTILS_TIME_UTIL_H

#include <ctime>
#include <string>
#include <unordered_map>
#include <cstdint>
#include <mutex>

#ifdef _WIN32
#include <windows.h>
#else
#include <sys/time.h>
#endif

namespace Base {
namespace Utils {
class TimeUtil final {
public:
    static constexpr const char* DEFAULT_TIME_FORMAT = "%Y-%m-%d %H:%M:%S";

    TimeUtil() = delete;
    TimeUtil(const TimeUtil&) = delete;
    TimeUtil& operator=(const TimeUtil&) = delete;

    /**
     * @brief 获取当前时间并填充到 tm 结构
     * @param output 输出参数，填充当前时间
     * 
     * 线程安全版本，使用 localtime_r 或 localtime_s
     */
    static void GetCurrentTimeStruct(struct tm& output);

    /**
     * @brief 获取当前时间的格式化字符串
     * @param format 时间格式，如 "%Y-%m-%d %H:%M:%S"
     * @return 格式化后的时间字符串
     * 
     * 自动缓存常用格式以提高性能
     */
    static std::string GetCurrentTimeString(const char* format = "%Y-%m-%d %H:%M:%S");

    template <size_t N>
    static std::string GetCurrentTimeString(const char (&format)[N]);

    /**
     * @brief 获取当前时间的格式化字符串（包含毫秒）
     * @param format 时间格式，如 "%Y-%m-%d %H:%M:%S"
     * @return 格式化后的时间字符串，自动追加毫秒部分（如 .123）
     * 
     * 例如：format 为 "%Y-%m-%d %H:%M:%S" 时，返回 "2025-09-23 14:30:25.123"
     */
    static std::string GetCurrentTimeStringWithMilliseconds(const char* format = "%Y-%m-%d %H:%M:%S");

    /**
     * @brief 获取当前毫秒级时间戳
     * @return 自 Unix 纪元起的毫秒数
     */
    static uint64_t GetCurrentMilliseconds();

    /**
     * @brief 获取当前微秒级时间戳
     * @return 自 Unix 纪元起的微秒数
     */
    static uint64_t GetCurrentMicroseconds();

    /**
     * @brief 获取当前纳秒级时间戳
     * @return 自 Unix 纪元起的纳秒数
     */
    static uint64_t GetCurrentNanoseconds();

    /**
     * @brief 格式化指定时间
     * @param t 时间值（秒数）
     * @param format 时间格式
     * @return 格式化后的时间字符串
     */
    static std::string FormatTime(time_t t, const char* format);

    template <size_t N>
    static std::string FormatTime(time_t t, const char (&format)[N]);

    /**
     * @brief 设置时区偏移
     * @param offset 时区偏移（小时），如东八区为 8
     */
    static void SetTimezone(int offset);

    /**
     * @brief 获取当前时区偏移
     * @return 时区偏移（小时）
     */
    static int GetTimezoneOffset();

private:
    static int timezoneOffset_; // 时区偏移（小时）
    static bool timezoneSet_;   // 时区是否已设置
};
} // namespace Utils
} // namespace Base

#endif // BASE_UTILS_TIME_UTIL_H